﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using QuestionsAnswers.UI.Models;

namespace QuestionsAnswers.UI.Controllers
{
    public class QuestionController : Controller
    {
        private readonly QuestionsAnswersContext _db = new QuestionsAnswersContext();
        private const int PageSize = 7;
        //
        // GET: /Question/

        public ViewResult Index(int sortType = 0, string courseFilter = "0", bool? unansweredFltrChk = null, int page = 1)
        {
            int sessionSort = 0;
            if (Session["sortType"] != null)
                sessionSort = (int)Session["sortType"];

            if (sortType == 0)
                sortType = sessionSort;

            if (sortType != 0)
                Session["sortType"] = sortType;

            bool? sessionUnansweredFilter = null;
            if (Session["unansweredFilter"] != null)
                sessionUnansweredFilter = (bool)Session["unansweredFilter"];

            if (unansweredFltrChk == null)
                unansweredFltrChk = sessionUnansweredFilter;

            if (unansweredFltrChk != null)
                Session["unansweredFilter"] = unansweredFltrChk;
            if (unansweredFltrChk == null)
                unansweredFltrChk = false;

            string sessionCourseFilter = "0";
            if (Session["courseFilter"] != null)
                sessionCourseFilter = (string)Session["courseFilter"];

            if (courseFilter == "0")
                courseFilter = sessionCourseFilter;

            if (courseFilter != "0")
                Session["courseFilter"] = courseFilter;

            List<Question> questions = unansweredFltrChk == true ? _db.Questions.Where(x => !x.Answers.Any()).ToList(): _db.Questions.ToList();
            if (courseFilter != "All" && courseFilter != "0")
            {
                int courseIdFilter = Convert.ToInt32(courseFilter);
                Course courseFilterCourse = _db.Courses.First(x => x.CourseId == courseIdFilter);
                questions = questions.Where(x => x.Courses != null && x.Courses.Contains(courseFilterCourse)).ToList();
            }
            if (sortType == 0 || sortType == 1)
                questions.Sort((x, y) => y.DateCreated.CompareTo(x.DateCreated));
            else if (sortType == 2)
                questions.Sort((x, y) => x.DateCreated.CompareTo(y.DateCreated));
            else if (sortType == 3)
            {
            }
            ViewBag.UnsansweredFltr = unansweredFltrChk;

            ViewBag.pagingInfo = new PagingInfo
                                     {
                                         CurrentPage = page,
                                         ItemsPerPage = PageSize,
                                         TotalItems = questions.Count()
                                     };
            List<SelectListItem> items = new List<SelectListItem>
                                             {
                                                 new SelectListItem{Text ="Select",
                                                     Value="0"
                                                 },
                                                 new SelectListItem
                                                     {
                                                         Text = "Newest",
                                                         Value = "1"
                                                     },
                                                 new SelectListItem
                                                     {
                                                         Text = "Oldest",
                                                         Value = "2",
                                                     },
                                                 new SelectListItem
                                                     {
                                                         Text = "Running",
                                                         Value = "3"
                                                     }
                                             };
            if (sortType != 0)
            {
                items.First(x => int.Parse(x.Value) == sortType).Selected = true;
            }
            ViewBag.DropDownSortItems = items;
            List<SelectListItem> coursesDropDownList = new List<SelectListItem>
                                                           {
                                                               new SelectListItem
                                                                   {
                                                                       Text = "All",
                                                                       Value = "All",
                                                                       Selected = true
                                                                   }
                                                           };
            if (User.Identity.IsAuthenticated)
            {
                var coursesList = _db.Users.First(x => x.UserName == User.Identity.Name).GetAllCourses().Distinct().ToList();
                coursesList.Sort((x, y) => x.Name.CompareTo(y.Name));

                foreach (Course course in coursesList)
                {
                    coursesDropDownList.Add(new SelectListItem { Text = course.Name, Value = course.CourseId.ToString() });
                }
            }
            if (courseFilter != "0" && courseFilter != "All")
            {
                coursesDropDownList.First(x => x.Value == courseFilter).Selected = true;
            }
            ViewBag.UsersCourses = coursesDropDownList;

            return View(questions.ToList().Skip((page - 1) * PageSize).Take(PageSize));
        }

        [Authorize]
        public ViewResult MyQuestions()
        {
            string userName = User.Identity.Name;
            var questions = _db.Questions.Include("User").Where(x => x.User.UserName == userName);
            return View("Index", questions);
        }


        [Authorize]
        public ActionResult Create()
        {
            ViewBag.Courses = GetCourseAssigns(null);
               
            return Request.IsAjaxRequest() ? PartialView() : (ActionResult)View();
        }


        [HttpPost]
        public ActionResult Create(Question question, List<CourseAssignViewModel> courseAssignViewModels,String listofT)
        {

            if (ModelState.IsValid)
            {
                foreach(string tag in listofT.Split(',').ToList())
                {
                    string tag1 = tag;
                    if (!_db.Tags.Where(y => y.Name == tag1).Any())
                        _db.Tags.Add(new Tag {Name = tag});
                }
                 _db.SaveChanges();              
                question.User = _db.Users.First(u => u.UserName == User.Identity.Name);
                question.Text = question.Text ?? "";
                question.Tags = listofT.Split(',').ToList().Select(x=>_db.Tags.First(y=>y.Name==x)).ToList();
                _db.Questions.Add(question);
                _db.SaveChanges();

                _db.Entry(SaveCourseAssigns(question.QuestionId, courseAssignViewModels)).CurrentValues.SetValues(question);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            User user = _db.Users.First(x => x.UserName == User.Identity.Name);

            List<Course> courses = _db.Courses.ToList().Where(x => x.Owners.Exists(y => y.UserName == user.UserName) || x.Participants.Exists(z => z.UserName == user.UserName) || x.Creator == user).ToList();
            ViewBag.CourseId = new SelectList(courses, "CourseId", "Name", question.Courses);
            ViewBag.Courses = GetCourseAssigns(null);
            return View(question);
        }

        // 
        // GET: /Question/Edit/5

        public ActionResult Edit(int id)
        {
            Question question = _db.Questions.Include("AssignedToUsers").Include("User").Include("Courses").Single(x => x.QuestionId == id);

            ViewBag.Courses = GetCourseAssigns(question); ;

            return Request.IsAjaxRequest() ? PartialView(question) : (ActionResult)View(question);
        }

        //
        // POST: /Question/Edit/5
        [Authorize]
        [HttpPost]
        public ActionResult Edit(Question question, List<CourseAssignViewModel> courseAssignViewModels)
        {


            if (ModelState.IsValid && User.Identity.Name == _db.Users.First(u => u.UserId == question.UserId).UserName)
            {
                Question questionInContext = SaveCourseAssigns(question.QuestionId, courseAssignViewModels);
                _db.Entry(questionInContext).CurrentValues.SetValues(question);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(question);
        }

        //
        // GET: /Question/Delete/5

        public ActionResult Delete(int id)
        {
            Question question = _db.Questions.Include(x => x.User).Where(y => y.QuestionId == id).First();
            return View(question);
        }

        //
        // POST: /Question/Delete/5
        [Authorize]
        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {

            Question question = _db.Questions.Include("User").First(q => q.QuestionId == id);

            if (User.Identity.Name == question.User.UserName)
            {
                _db.Questions.Remove(question);
                _db.SaveChanges();
            }

            return RedirectToAction("Index");
        }

        [Authorize]
        public ActionResult ModifyCourseUsers(int id)
        {
            Question question = _db.Questions.Include("AssignedToUsers").Include("User").Include("Courses").Single(x => x.QuestionId == id);
            ViewBag.Question = question;
            return View(GetCourseAssigns(question));
        }

        [Authorize]
        [HttpPost]
        public ActionResult ModifyCourseUsers(int questionId, List<CourseAssignViewModel> courseAssignViewModels)
        {
            if (ModelState.IsValid)
            {
                Question question = SaveCourseAssigns(questionId, courseAssignViewModels);
                _db.Entry(question).State = EntityState.Modified;
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            return RedirectToAction("ModifyCourseUsers", new { id = questionId });
        }

        public List<CourseAssignViewModel> GetCourseAssigns(Question question)
        {


            User user =
                _db.Users.Include("Participating").Include("Owning").Include("Created").First(
                    x => x.UserName == User.Identity.Name);
            return (from c in user.GetAllCourses().Distinct()
                    select new CourseAssignViewModel()
                    {
                        Selected = question !=null && (question.Courses.Exists(x => x.CourseId == c.CourseId)),
                       Course = c,
                        Users  = (from u in c.GetAllUsers().Distinct()
                                         select new UserCourseAssignViewModel()
                                               {
                                                   Text = u.UserName,
                                                   Value = u.UserId.ToString(),
                                                   Selected = question !=null &&_db.AssignedToUsers.Any(x => x.CourseId == c.CourseId && x.QuestionId == question.QuestionId && x.UserId == u.UserId),
                                                   NumberOfQuestionAskedForCourse = _db.Questions.Where(x => x.User.UserName == User.Identity.Name && x.Courses.Any(y=>y.CourseId==c.CourseId)).Count(),
                                                   NumberOfQuestionAssignedForCourse = _db.AssignedToUsers.Where(x=>x.User.UserName==u.UserName &&x.CourseId==c.CourseId).Count()
                                               }).ToList()



                    }).ToList();
        }
        public Question SaveCourseAssigns(int questionId, List<CourseAssignViewModel> courseAssignViewModels)
        {
            Question questionInContext = _db.Questions.Include("Courses").Single(x => x.QuestionId == questionId);
            if (courseAssignViewModels != null)
            {

                foreach (var courseAssignViewModel in courseAssignViewModels)
                {
                    var course = _db.Courses.Find(courseAssignViewModel.Course.CourseId);
                    if (courseAssignViewModel.Selected)
                    {
                        if (!questionInContext.Courses.Contains(course))
                            questionInContext.Courses.Add(course);

                    }
                    else
                    {
                        questionInContext.Courses.Remove(course);
                    }

                    foreach (UserCourseAssignViewModel user in courseAssignViewModel.Users)
                    {                     
                        var thisUser = _db.Users.Find(int.Parse(user.Value));
                        AssignedToUser assign = _db.AssignedToUsers.FirstOrDefault(y => y.CourseId == course.CourseId && y.QuestionId == questionInContext.QuestionId && y.UserId == thisUser.UserId);
                        if (user.Selected)
                        {
                            if (assign == null)
                            {
                                _db.AssignedToUsers.Add(new AssignedToUser
                                {
                                    Course = course,
                                    Question = questionInContext,
                                    User = thisUser
                                });
                            }
                        }
                        else
                        {
                            if (assign != null)
                                _db.AssignedToUsers.Remove(assign);
                        }
                    }
                }
            }
            return questionInContext;
        }

        protected override void Dispose(bool disposing)
        {
            _db.Dispose();
            base.Dispose(disposing);
        }
    }
}